package problems.rdm;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.IntSummaryStatistics;

import globals.CentralStatics;
import problems.TransitionFunction;
import problems.maze20.Maze20States;
import problems.maze20.Maze20Transitions;
import problems.rdmthreeobjectives.RDMTransitionProb;

public class RDMTransitions implements TransitionFunction<Integer, Integer>{
	
	private static RDMTransitions trans = null;
	
	double MC_MST[]= {0.9,0.8,0.75,0.7};
	double MR_MST[]= {0.4,0.45,0.4,0.45};
	
	
	double MC_RT[]= {0.45,0.47,0.35,0.3};
	double MR_RT[]= {0.9,0.75,0.8,0.65};
	
	
	
	
	int casenum;
	

	@Override
	public double probabilityOfTransition(Integer state, Integer action, Integer statePrime) {
		// TODO Auto-generated method stub
		
						//Alternate code by calling the probabilityVector() method
				double[] vec = this.probabilityVector(state, action);
				return vec[statePrime.intValue()];
		//need to check it
		//return 0;
		
	}

	//From Maze20 class
	@Override
	public double[] probabilityVector(Integer state, Integer action) {
		// TODO Auto-generated method stub
		double[] vec = {0,0,0,0};
		
		//RDMTransitionProbability rtp=new RDMTransitionProbability();
		
		//For MST
				//First Case
				if(action.equals(RDMActions.MST)&&state.equals(RDMStates.S1)){
					
					vec[0]=0.8188;
					vec[1]=0.0712;
					vec[2]=0.1012;
					vec[3]=0.0088;
					//casenum=0;
					//vec=getCaseMST(casenum);
					
					
				}
				
				
				//Second Case
				if(action.equals(RDMActions.MST)&&state.equals(RDMStates.S2)){
					
					
					vec[0]=0.8188;
					vec[1]=0.1012;
					vec[2]=0.0712;
					vec[3]=0.0088;
					
					//casenum=1;
					//vec=getCaseMST(casenum);
					
					
					
				}


				
				//third case
				
				if(action.equals(RDMActions.MST)&&state.equals(RDMStates.S3)){
					
					
					
					
					vec[0]=0.8064;
					vec[1]=0.0336;
					vec[2]=0.1536;
					vec[3]=0.0064;
					
					//casenum=2;
					//vec=getCaseMST(casenum);
				}
					
				
				//Fourth case
				
				if(action.equals(RDMActions.MST)&&state.equals(RDMStates.S4)){
					
					
					
					vec[0]=0.7917;
					vec[1]=0.0783;
					vec[2]=0.1183;
					vec[3]=0.0117;
					
					//casenum=3;
					//vec=getCaseMST(casenum);
					
				}
				
				//For RT
				//First Case
						if(action.equals(RDMActions.RT)&&state.equals(RDMStates.S1)){
							
							
												
							vec[0]=0.833;
							vec[1]=0.017;
							vec[2]=0.147;
							vec[3]=0.003;
							
							//casenum=0;
							//vec=getCaseRT(casenum);
						}
						//Second Case
						if(action.equals(RDMActions.RT)&&state.equals(RDMStates.S2)){
							
							
													
							
							
							vec[0]=0.8448;
							vec[1]=0.0352;
							vec[2]=0.1152;
							vec[3]=0.0048;
							
							//casenum=1;
							//vec=getCaseRT(casenum);
						
							
						}
						
						//third case
						
						if(action.equals(RDMActions.RT)&&state.equals(RDMStates.S3)){
							
							
							
							vec[0]=0.7227;
							vec[1]=0.0073;
							vec[2]=0.2673;
							vec[3]=0.0027;
							
							//casenum=2;
							//vec=getCaseRT(casenum);
							
							
						}
						
						//Fourth case
						
						if(action.equals(RDMActions.RT)&&state.equals(RDMStates.S4)){
							
							
							
							vec[0]=0.7372;
							vec[1]=0.0228;
							vec[2]=0.2328;
							vec[3]=0.0072;
							
							//casenum=3;
							//vec=getCaseRT(casenum);
							
						}
							
				
		
		return vec;
	}

	//From Maze20 class, not satisfied with it
	//problem in this method
	@Override
	public Integer nextState(Integer currentState, Integer action) {
		// TODO Auto-generated method stub
		
		//Exceptional case to avoid nullpointer exception
		if(action==null)
		{
			return currentState;
		}
						
		double r = CentralStatics.getCentralRandom().nextDouble();
		
		double[] vec = this.probabilityVector(currentState, action);
		double prob = 0.0;
		RDMStates s = RDMStates.getStates(); //returns an object of RDMStates type
		
		for(int i=0; i<vec.length; i++){
			
			prob += vec[i];
			
			if(r<=prob){

				
				if(i==RDMStates.S1.intValue())
				{
				
				return RDMStates.S1;
				}
				if(i==RDMStates.S2.intValue())
				{
				
				return RDMStates.S2;
				}
				if(i==RDMStates.S3.intValue())
				{
				
				return RDMStates.S3;
				}
				if(i==RDMStates.S4.intValue())
				{
				
				return RDMStates.S4;
				}
		}
		}
		
		return null;
	}
	
	//Method to return an object of RDMTransitions class
	public static RDMTransitions getTransitions(){
		if(RDMTransitions.trans ==null){
			RDMTransitions.trans = new RDMTransitions();
		}
		return RDMTransitions.trans;
	}
	
	
	
	
	//stable scenario
	
		public double[] getCaseRT(int casenum)
		{
			double vec1[]=new double[4];
		    
			vec1[0]=(MC_RT[casenum])*(MR_RT[casenum]);
			vec1[1]=(MC_RT[casenum])*((1-MR_RT[casenum]));
			vec1[2]=((1-MC_RT[casenum]))*(MR_RT[casenum]);
			vec1[3]=((1-MC_RT[casenum]))*((1-MR_RT[casenum]));
			
			
			return vec1;
			
		}
		
		///stable scenario
		public double[] getCaseMST(int casenum)
		{
			double vec1[]=new double[4];
			vec1[0]=(MC_MST[casenum])*(MR_MST[casenum]);
			vec1[1]=(MC_MST[casenum])*((1-MR_MST[casenum]));
			vec1[2]=((1-MC_MST[casenum]))*(MR_MST[casenum]);
			vec1[3]=((1-MC_MST[casenum]))*((1-MR_MST[casenum]));
			
			
			return vec1;
			
		}
		

}
